package com.xuyuan.json.gson;

import com.google.gson.*;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import lombok.Data;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.math.BigDecimal;

public class GsonTest {

    @Test
    public void test0() {
        /*建造者构建*/
        Gson gson1 = new GsonBuilder().create();
        /*直接构建*/
        Gson gson2 = new Gson();

    }

    /**
     * 序列化+反序列化使用
     */
    @Test
    public void test() {
        Gson gson = new GsonBuilder().create();
        TestProduct1 testProduct = new TestProduct1();
        testProduct.setProductName("白悟空");
        testProduct.setProductId("123456");
        testProduct.setProductType("game");
        testProduct.setProductPrice(new BigDecimal(1000));
        testProduct.setProductDesc("great experience");
        String json = gson.toJson(testProduct);
        System.out.println(json);

        TestProduct2 testProduct2 = gson.fromJson(json, TestProduct2.class);
        System.out.println(testProduct2);
    }

    /**
     * GSON的配置
     */
    @Test
    public void test2() {
        // Gson gson = new GsonBuilder()
        //         .setPrettyPrinting() // 使输出的JSON格式化为易读的格式。
        //         .setFormattingStyle() // 自定义JSON格式化输出格式
        //         .setDateFormat() // 设置日期格式
        //         .setExclusionStrategies() // 设置序列化和反序列化的排除策略，实现ExclusionStrategy接口，重写方法筛选不需要序列化的类里面不需要的属性
        //         .setFieldNamingPolicy() // 设置字段命名策略
        //         .setFieldNamingStrategy() // 设置字段命名策略
        //         .setVersion() // 设置版本控制，序列化时只处理指定版本的字段
        //         .setStrictness()
        //         .setLongSerializationPolicy() // 设置长整型的序列化策略。
        //         .setNumberToNumberStrategy() // 已废弃，建议使用NumberTypeAdapterFactory
        //         .setObjectToNumberStrategy() // 已废弃，建议使用NumberTypeAdapterFactory
        //         .addDeserializationExclusionStrategy() // 添加反序列化排除策略
        //         .addSerializationExclusionStrategy() // 添加序列化排除策略
        //         .disableHtmlEscaping() //  禁用HTML字符转义
        //         .disableJdkUnsafe() // 禁用对不安全JDK类型的支持
        //         .disableInnerClassSerialization() // 禁用内部类的序列化
        //         .enableComplexMapKeySerialization() // 启用复杂类型的Map键序列化
        //         .excludeFieldsWithModifiers() //  排除具有指定修饰符的字段。
        //         .registerTypeAdapter() // 注册自定义类型适配器
        //         .registerTypeAdapterFactory() // 注册自定义类型适配器工厂
        //         .registerTypeHierarchyAdapter() // 注册自定义类型适配器，自定义序列化和反序列化
        //         .serializeNulls() // 序列化空值
        //         .create();
    }


    /**
     * JsonReader使用
     */
    @Test
    public void test3() throws IOException {
        String json = "{'id': 1001,'firstName': 'xu','lastName': 'yuan','email': null}";
        JsonReader jsonReader = new JsonReader(new StringReader(json));
        jsonReader.setLenient(true);
        try {
            while (jsonReader.hasNext()) {
                JsonToken nextToken = jsonReader.peek();
                if (JsonToken.BEGIN_OBJECT.equals(nextToken)) {
                    jsonReader.beginObject();
                } else if (JsonToken.NAME.equals(nextToken)) {
                    String name = jsonReader.nextName();
                    System.out.println("Token KEY >>>> " + name);
                } else if (JsonToken.STRING.equals(nextToken)) {
                    String value = jsonReader.nextString();
                    System.out.println("Token Value >>>> " + value);
                } else if (JsonToken.NUMBER.equals(nextToken)) {
                    long value = jsonReader.nextLong();
                    System.out.println("Token Value >>>> " + value);
                } else if (JsonToken.NULL.equals(nextToken)) {
                    jsonReader.nextNull();
                    System.out.println("Token Value >>>> null");
                } else if (JsonToken.END_OBJECT.equals(nextToken)) {
                    jsonReader.endObject();
                }
            }
        } catch (IOException e) {

        } finally {
            jsonReader.close();
        }
    }

    /**
     * JsonReader使用
     */
    @Test
    public void test3_1() throws IOException {
        String json = "{\"name\":\"John Doe\",\"age\":25,\"addresses\":[{\"street\":\"123 Main St\",\"city\":\"Anytown\"}]}";
        JsonReader jsonReader = new JsonReader(new StringReader(json));
        jsonReader.beginObject(); // Start reading the outer object

        while (jsonReader.hasNext()) {
            String name = jsonReader.nextName();

            if (name.equals("name")) {
                System.out.println("Name: " + jsonReader.nextString());
            } else if (name.equals("age")) {
                System.out.println("Age: " + jsonReader.nextInt());
            } else if (name.equals("addresses")) {
                jsonReader.beginArray();

                while (jsonReader.hasNext()) {
                    jsonReader.beginObject();

                    while (jsonReader.hasNext()) {
                        String fieldName = jsonReader.nextName();
                        if (fieldName.equals("street")) {
                            System.out.println("Street: " + jsonReader.nextString());
                        } else if (fieldName.equals("city")) {
                            System.out.println("City: " + jsonReader.nextString());
                        }
                    }
                    jsonReader.endObject();
                }
                jsonReader.endArray();
            }
        }
        jsonReader.endObject();
        jsonReader.close();

    }

    /**
     * JsonParser的使用
     */
    @Test
    public void test4() {
        String json = "{'id': 1001,'firstName': 'xu','lastName': 'yuan','email': null}";
        JsonElement jsonElement = new JsonParser().parse(json);
        JsonObject jsonObject = jsonElement.getAsJsonObject();

        System.out.println(jsonObject.get("id"));
        System.out.println(jsonObject.get("firstName"));
        System.out.println(jsonObject.get("lastName"));
        System.out.println(jsonObject.get("email"));
    }

    @Test
    public void test5() {
        String json = "{'id': 1001,'firstName': 'xu','lastName': 'yuan','email': null}";
        JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);

        System.out.println(jsonObject.get("id"));
        System.out.println(jsonObject.get("firstName"));
        System.out.println(jsonObject.get("lastName"));
        System.out.println(jsonObject.get("email"));
    }

    /**
     * JsonWriter使用
     */
    @Test
    public void test6() throws IOException {
        StringWriter stringWriter = new StringWriter(1024);
        JsonWriter jsonWriter = new JsonWriter(stringWriter);
        jsonWriter.beginObject();
        jsonWriter.name("name").value("xuyuan");
        jsonWriter.name("age").value(25);

        jsonWriter.name("addresses");
        jsonWriter.beginArray();
        jsonWriter.beginObject();
        jsonWriter.name("street").value("123 Main St");
        jsonWriter.name("city").value("Anytown");
        jsonWriter.endObject();
        jsonWriter.endArray();

        jsonWriter.endObject();
        jsonWriter.flush();
        jsonWriter.close();
        System.out.println(stringWriter);
    }

    @Data
    class TestProduct1 {
        private String productName;
        private String productId;
        private String productType;
        private BigDecimal productPrice;
        private String productDesc;
    }

    @Data
    class TestProduct2 {
        private String productName;
        private String productId;
        private String productType;
        private BigDecimal productPrice;
        private String productDesc;
    }
}

